package com.zhima.listener;

import cn.hutool.core.codec.Base64;
import com.zhima.constant.JudgeMqConstant;
import com.zhima.dto.AiGuide;
import com.zhima.dto.FeignJudgeRecordDTO;
import com.zhima.dto.FeignQuestionJudgeInfoDTO;
import com.zhima.dto.JudgeSubmissionMessageDTO;
import com.zhima.enums.JudgeState;
import com.zhima.feignclient.JudgeRecordFeignClient;
import com.zhima.feignclient.QuestionFeignClient;
import com.zhima.handler.AbstractJudgerHandler;
import com.zhima.properties.ZhimaJudgerProperties;
import com.zhima.util.AiUtil;
import com.zhima.util.JudgerManager;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


@Component
public class RabbitMqListener {

    @Autowired
    private QuestionFeignClient questionFeignClient;

    @Autowired
    private JudgeRecordFeignClient judgeRecordFeignClient;

    @Autowired
    private ZhimaJudgerProperties zhimaJudgerProperties;

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = JudgeMqConstant.SUBMIT_QUEUE_NAME, durable = "true"),
            exchange = @Exchange(value = JudgeMqConstant.EXCHANGE_NAME, ignoreDeclarationExceptions = "true"),
            key = JudgeMqConstant.SUBMIT_QUEUE_BINDING_KEY
    ))
    public void handleJudgeMessage(JudgeSubmissionMessageDTO judgeSubmissionMessageDTO) throws InterruptedException {
        if (judgeSubmissionMessageDTO.getSubmissionRecordId() == null) {
            return;
        }
        Long nowVersion = questionFeignClient.queryQuestionVersion(judgeSubmissionMessageDTO.getQuestionId());
        // 题目版本不一致
        if (!judgeSubmissionMessageDTO.getVersion().equals(nowVersion)) {
            judgeRecordFeignClient.updateJudgeRecordState(judgeSubmissionMessageDTO.getSubmissionRecordId(), JudgeState.VERSION_CONFLICT.name());
            return;
        }
        FeignJudgeRecordDTO feignJudgeRecordDTO = judgeRecordFeignClient.queryJudgeRecordById(judgeSubmissionMessageDTO.getSubmissionRecordId());
        FeignQuestionJudgeInfoDTO feignQuestionJudgeInfoDTO = questionFeignClient.queryQuestionJudgeInfo(judgeSubmissionMessageDTO.getQuestionId());
        // 根据配置得到判题的处理器
        AbstractJudgerHandler abstractJudgerHandler = JudgerManager.getJudger(zhimaJudgerProperties.getJudgerType());
        // 正在编译
        judgeRecordFeignClient.updateJudgeRecordState(judgeSubmissionMessageDTO.getSubmissionRecordId(), JudgeState.COMPILING.name());
        // 编译失败
        if (!abstractJudgerHandler.compile(feignJudgeRecordDTO, feignQuestionJudgeInfoDTO)) {
            judgeRecordFeignClient.updateJudgeRecordState(judgeSubmissionMessageDTO.getSubmissionRecordId(), JudgeState.COMPILE_ERROR.name());
            // 获取AI测评结果和指导意见
            judgeRecordFeignClient.aiGuide(new AiGuide(judgeSubmissionMessageDTO.getSubmissionRecordId().toString(), AiUtil.completionsWithParams(Base64.decodeStr(feignJudgeRecordDTO.getSourceCode()), feignJudgeRecordDTO.getCodeLanguageName())));
            return;
        }
        // 测评中
        judgeRecordFeignClient.updateJudgeRecordState(judgeSubmissionMessageDTO.getSubmissionRecordId(), JudgeState.JUDGING.name());
        abstractJudgerHandler.handle(feignJudgeRecordDTO, feignQuestionJudgeInfoDTO);
    }
}
